package com.bbcare.followup.plat.task;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.bbcare.followup.plat.entity.Patient;
import com.bbcare.followup.plat.service.FuClosecaseRecordService;
import com.bbcare.followup.plat.service.IPatientService;
import com.bbcare.followup.plat.service.impl.PatientService;
import com.bbcare.followup.plat.store.ibatis.IPatientDAO;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import org.springframework.beans.factory.annotation.Autowired;

import com.bbcare.comm.Constants;
import com.bbcare.comm.DateUtil;
import com.bbcare.comm.enumeration.MessageTypeEnum;
import com.bbcare.followup.plat.entity.MessageNotifyRecord;
import com.bbcare.followup.plat.entity.PatientTask;
import com.bbcare.followup.plat.store.ibatis.IConfCacheDAO;
import com.bbcare.followup.plat.store.ibatis.IMessageNotifyRecordDAO;
import com.bbcare.followup.plat.service.IXCXService;


/**
 * 小程序相关的定时任务类。
 */
public class XCXJob implements Job  {
    private final static Log logger = LogFactory.getLog(XCXJob.class);

    @Autowired
    private IConfCacheDAO confCacheDao; //定时任务的配置表。

    @Autowired
    private IPatientDAO patientDao;

    @Autowired
    private IXCXService xcxService; //小程序服务类。

    @Autowired
    private IPatientService patientService;

    @Autowired
    private FuClosecaseRecordService closecaseService;


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        logger.info("++++execute() 小程序定时任务开始执行。");

        List<Map<String, Object>> ruleList = null;  //通知消息规则。
        Map<String, Object> paraMap = new HashMap<String, Object>();
        paraMap.put("status",       Constants.TABLE_RECORD_STATUS_NOMAL); //查询fu_informrule_dict表中的有效记录。
        paraMap.put("queueStatus",  Constants.QUEUE_STATUS_NOMAL);   //查询fu_informrule_dict表时关联fu_queue_info的队列状态要求。
        paraMap.put("informType",   Constants.FU_INFORM_RULE_TYPE_WECHAT);  //仅处理微信提醒消息。
        paraMap.put("ruleType",     Constants.FU_INFORM_RULE_SMS_SEND_RULE_TYPE_WIN);//按窗口期规则发送。
        try {
            logger.info("++++execute() begin to call confCacheDao.queryXcxRule(paraMap).");
            ruleList = confCacheDao.queryXcxRule(paraMap);
            logger.info("++++execute() finish to call confCacheDao.queryXcxRule(paraMap).");
            if (null == ruleList || ruleList.isEmpty()) {
                //没有查询到有效的小程序相关的任务规则。
                logger.info("++++execute() 没有查询到有效的小程序相关的任务规则。");
                return;
            } else {
                logger.info("++++execute() 查询到有效的小程序相关的任务规则"+ruleList.size()+"条。");
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage());
            return;
        }

        List<PatientTask> taskList = null;
        String queueId,patUserId;
        Integer beforeDays;
        MessageNotifyRecord wxMsg;
        List<Patient> patList;
        Patient pat;
        int saveCnt = 0;
        Map<String, Object> paramIn = new HashMap<String, Object>();
        logger.info("++++execute() begin to for ruleList.");
        for(Map<String, Object> rule : ruleList)    {
            queueId = (String) rule.get("queueId");
            beforeDays  = (Integer)rule.get("beforeDays");   //就诊日前N天发送提醒消息。
            paramIn.put("beforeDays", beforeDays);    //就诊日前N天发送提醒消息。
            paramIn.put("queueId",      queueId);   // 队列id。
            try {
                /*
                 * beforeDays的用法：如果今天是3/19日，beforeDays是3，则下次就诊日是3/23的患者任务需要发送提醒消息。
                 */
                logger.info("++++execute() begin to call xcxService.queryWindowTasks().");
                taskList = xcxService.queryWindowTasks(paramIn);//查询本规则下的任务。
                if (null == taskList || taskList.isEmpty()) {
                    //没有需要发送的下次检查提醒。
                    logger.info("++++execute() 没有需要发送的下次检查提醒。");
                    continue;
                } else {
                    final int patSize   = taskList.size();
                    //保存这些可能需要发送的下次门诊提醒消息到fu_message_notify_record。
                    logger.info("++++execute() 保存这些可能需要发送的下次门诊提醒消息共"+patSize+"条到fu_message_notify_record。");
                    for(PatientTask task : taskList)   {
                        patUserId   = task.getUserId();
                        //查询该患者是否有结案记录，有的话则不需要推送消息、
                        int count   = closecaseService.countByUserid(patUserId);
                        if(count > 0){
                            logger.info("++++execute() 由于userId:"+patUserId+"已结案，所以无需保存。");
                            continue;
                        } else {
                            if (xcxService.insertXcxMsg(task)) {
                                saveCnt++;
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                logger.info(ex.getMessage());
                return;
            }
        }

        logger.info("++++execute() 小程序定时任务中，保存了"+saveCnt+"条小程序下次检查提醒消息。");
        logger.info("++++execute() 小程序定时任务结束执行。");
    }
}
